package com.play.springflux.controller;

import com.play.springflux.model.User;
import com.play.springflux.repository.UserRepository;
import com.play.springflux.util.CheckUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import javax.validation.Valid;

@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserRepository userRepository;

    @GetMapping("/")
    public Flux<User> getAll() {
        return userRepository.findAll();
    }

    @PostMapping("/")
    public Mono<User> crete(@Valid @RequestBody User user) {
        CheckUtil.checkName(user.getName());
        return userRepository.save(user);
    }

    @GetMapping(value = "/getAllStream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<User> getStreamAll() {
        return userRepository.findAll();
    }

    @DeleteMapping("/{id}")
    public Mono<ResponseEntity<Void>> delete(@PathVariable String id) {
        return userRepository.findById(id)
                .flatMap(user -> userRepository.delete(user)
                        .then(Mono.just(new ResponseEntity<Void>(HttpStatus.OK))))
                .defaultIfEmpty(new ResponseEntity<>(HttpStatus.NOT_FOUND));
    }

    @PutMapping("/{id}")
    public Mono<ResponseEntity<User>> update(@PathVariable String id, @Valid @RequestBody User user) {
//        flatMap 操作数据
//        Map 转换数据
        CheckUtil.checkName(user.getName());
        return userRepository.findById(id).flatMap(u -> {
                    u.setAge(user.getAge());
                    u.setName(user.getName());
                    return userRepository.save(u);
                }).map(u -> new ResponseEntity<>(u, HttpStatus.OK))
                .defaultIfEmpty(new ResponseEntity<>(HttpStatus.NOT_FOUND));
    }

    @GetMapping("/{id}")
    public Mono<ResponseEntity<User>> findById(@PathVariable String id) {
//        flatMap 操作数据
//        Map 转换数据
        return userRepository.findById(id).map(u -> new ResponseEntity<>(u, HttpStatus.OK))
                .defaultIfEmpty(new ResponseEntity<>(HttpStatus.NOT_FOUND));
    }

    @GetMapping(value = "/stream/age/{start}/{end}", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<User> getUserByAgeStream(@PathVariable int start, @PathVariable int end) {
        return userRepository.findUserByAgeBetween(start, end);
    }

    @GetMapping(value = "/age/{start}/{end}")
    public Flux<User> getUserByAge(@PathVariable int start, @PathVariable int end) {
        return userRepository.findUserByAgeBetween(start, end);
    }
}
